IF CSS получает встроенные условные операторы - Web-Global: Связывая миры через веб-технологии

IF CSS получает встроенные условные операторы

Пост опубликован 19 июля 2024 в 18:49 и находится в рубриках HTML&CSS. 33
Поделиться:

Несколько сирен прозвучали пару недель назад, когда рабочая группа CSS (CSSWG) решила добавить if()условный оператор в спецификацию CSS Values ​​Module Level 5. Мое внимание привлек пост Лии Веру X в тот же день:

Исторический день для CSS 😀🎉
Если вы пишете какие-либо компоненты, используемые и/или стилизованные другими, вы знаете, насколько это важно!
background: if(style(–variant: success), var(–green));
Даже если вы этого не сделаете, это позволит делать такие вещи, как:padding: if(var(–2xl), 1em, var(–xl) или var(–m),… pic.twitter.com/cXeqwBuXvK— Леа Вероу (@LeaVerou) 

13 июня 2024 г.

Лия — та, кто открыла проблему на GitHub, приведшую к обсуждению, и по счастливому совпадению — или, может быть, по счастливой случайности — решение пришло в ее день рождения. Это должен был быть довольно бурный день! Что вы получили на свой день рождения? «О, вы знаете, просто принятое предложение по спецификации CSS». Дико, просто дико.

Принятое предложение — это зеленый свет для CSSWG, чтобы работать над идеей с намерением распространить проект спецификации для дальнейшего внесения и рассмотрения на пути, как мы надеемся, к тому, чтобы он стал рекомендуемой функцией CSS. Так что, это будет горячая минута, прежде чем что-либо из этого будет готово, то есть, если это будет готово полностью.

Но идея применения стилей на основе условного требования очень захватывающая и стоит того, чтобы взглянуть на нее пораньше. Я набросал несколько заметок об этом в своем блоге в тот же день, когда Ли опубликовала пост в X, и подумал, что вынесу их сюда для потомков, а также соберу больше подробностей, которые появились с тех пор.

Это не новая идея.

Многие предложения рождаются из ранее отклоненных предложений и if()ничем не отличаются. И, действительно, в последние дни мы получили несколько функций CSS, которые позволяют использовать условную стилизацию — :has()и запросы стилей контейнеров являются двумя наиболее очевидными примерами. Ли даже приводит тикет 2018 года , который выглядит и читается очень похоже на принятое предложение.

Разница?

Запросы стилей уже были реализованы, и мы могли просто ссылаться на тот же синтаксис для условий (плюс  media() и  supports() из   предложения Таба @when ), тогда как в предложении 2018 года то, как будут работать условия, было в значительной степени не определено.Леа Вероу, «Встроенные условные операторы в CSS?»

Мне нравится, как Ли указывает на то, что CSS продолжает описывать, что CSS всегда был условным языком:

Ребята… В CSS с самого начала были условные операторы. Каждый селектор по сути является условным оператором!Леа Вероу, «Встроенные условные операторы в CSS?»

Правда! Cascade — это средство оценки селекторов и сопоставления их с элементами HTML на странице. То, что if()приносит в таблицу, — это способ записи встроенных условий с селекторами.

Синтаксис

Все сводится к следующему:

<if()> = if( <container-query>, [<declaration-value>]{1, 2} )

…где:

  • Значения могут быть вложенными для создания нескольких ветвей.
  • Если третий аргумент не указан, он становится эквивалентом пустого потока токенов.

Все это на данный момент концептуально, и ничего не высечено на камне. Мы, вероятно, увидим изменения, пока CSSWG работает над этой функцией. Но в текущем виде идея, похоже, вращается вокруг указания условия и установки одного из двух объявленных стилей — одного как стиля «по умолчанию» и одного как «обновленного» стиля при совпадении.

.element {
  background-color:
    /* If the style declares the following custom property: */
    if(style(--variant: success),
      var(--color-green-50), /* Matched condition */
      var(--color-blue-50);  /* Default style */
    );
}

В этом случае мы ищем style()условие, при котором переменная CSS --variantобъявляется и ей присваивается значение success, и:

  • …если --variantустановлено значение success, мы устанавливаем значение , successкоторое --color-green-50является переменной, сопоставленной некоторому значению зеленоватого цвета.
  • …если --variantне установлено значение success, мы устанавливаем значение , successкоторое --color-blue-50является переменной, сопоставленной с некоторым значением голубоватого цвета.

Стиль по умолчанию необязателен, поэтому я думаю, что в некоторых случаях его можно опустить для лучшей читаемости:

.element {
  background-color:
    /* If the style declares the following custom property: */
    if(style(--variant: success),
      var(--color-green-50) /* Matched condition */
    );
}

В определении синтаксиса выше упоминается, что мы могли бы поддерживать третий аргумент в дополнение к соответствующему условию и стилю по умолчанию, что позволяет нам вкладывать условия друг в друга:

background-color: if(
  style(--variant: success), var(--color-success-60), 
    if(style(--variant: warning), var(--color-warning-60), 
      if(style(--variant: danger), var(--color-danger-60), 
        if(style(--variant: primary), var(--color-primary)
      )
    ),
  )
);

Ой, похоже, там происходит какая-то дикая инициация! Ли продолжает предлагать синтаксис, который приведет к гораздо более плоской структуре:

<if()> = if( 
  [ <container-query>, [<declaration-value>]{2}  ]#{0, },
  <container-query>, [<declaration-value>]{1, 2} 
)

Другими словами, вложенные условия гораздо более плоские, поскольку их можно объявить  
вне  начального условия. Та же концепция, что и раньше, но другой синтаксис:

background-color: if(
  style(--variant: success), var(--color-success-60), 
  style(--variant: warning), var(--color-warning-60),
  style(--variant: danger), var(--color-danger-60), 
  style(--variant: primary), var(--color-primary)
);

Таким образом, вместо того, чтобы помещать одно 
if()утверждение в другое 
if(), мы можем объединить все возможные условия соответствия в одно утверждение.

Мы пытаемся сопоставить if()условие, запрашивая стили элемента. Соответствующей size()функции для запроса измерений нет — запросы контейнера неявно предполагают размер:

.element {
  background: var(--color-primary);

  /* Condition */
  @container parent (width >= 60ch) {
    /* Applied styles */
    background: var(--color-success-60);
  }
}

А запросы контейнера становятся запросами 
стиля , когда мы вместо этого вызываем 
style()функцию:

.element {
  background: orangered;

  /* Condition */
  @container parent style(--variant: success) {
    /* Applied styles */
    background: dodgerblue;
  }
}

Запросы стиля кажутся мне гораздо более осмысленными, когда они рассматриваются в контексте if(). Без if()легко усомниться в общей полезности запросов стиля . Но в этом свете становится ясно, что запросы стиля являются частью гораздо более обширной картины, которая выходит за рамки одних только запросов контейнеров.

Еще много чего нужно выяснить о синтаксисе if(). Например, Таб Аткинс описывает возможный сценарий , который может привести к путанице между тем, что такое совпадающее условие и параметрами стиля по умолчанию. Так что, кто знает, чем все это в итоге обернется!

Условия, поддерживающие другие условия

Как мы уже отметили, if()это далеко не единственный тип условной проверки, уже предусмотренный в CSS. Как бы выглядело написание встроенного условного оператора, который проверяет другие условия, такие как @supportsи @media?

В коде:

background-color: if(
  supports( /* etc. */ ),
  @media( /* etc. */ )
);

Проблема будет в контейнере, поддерживающем запросы размера. Как упоминалось ранее, явной функции нет  
size() ; вместо этого это больше похоже на анонимную функцию.